home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-21 | 11.0 KB | 462 lines | [TEXT/ttxt] |
- --<<<
-
- in module HTMLImplementation
-
- class HTMLDisplayer ()
- instance variables
- stream
- pres
- txt
- targetText
- currentStyle
- styleStack
- url
- anchorStart
- anchorURL
- callback
- state
- title
- startX
- startY
- myParentGroup
- myBoundary
- browser
- end
-
- -- Perhaps HTMLStream should define all of these automatically.
-
- global HTML_A := 0
- global HTML_ABBREV := 1
- global HTML_ABSTRACT := 2
- global HTML_ACRONYM := 3
- global HTML_ADDED := 4
- global HTML_ADDRESS := 5
- global HTML_ARG := 6
- global HTML_B := 7
- global HTML_BASE := 8
- global HTML_BLOCKQUOTE := 9
- global HTML_BODY := 10
- global HTML_BOX := 11
- global HTML_BR := 12
- global HTML_BYLINE := 13
- global HTML_CAPTION := 14
- global HTML_CHANGED := 15
- global HTML_CITE := 16
- global HTML_CMD := 17
- global HTML_CODE := 18
- global HTML_COMMENT := 19
- global HTML_DD := 20
- global HTML_DFN := 21
- global HTML_DIR := 22
- global HTML_DL := 23
- global HTML_DT := 24
- global HTML_EM := 25
- global HTML_FIG := 26
- global HTML_FOOTNOTE := 27
- global HTML_FORM := 28
- global HTML_H1 := 29
- global HTML_H2 := 30
- global HTML_H3 := 31
- global HTML_H4 := 32
- global HTML_H5 := 33
- global HTML_H6 := 34
- global HTML_H7 := 35
- global HTML_HEAD := 36
- global HTML_HR := 37
- global HTML_HTML := 38
- global HTML_HTMLPLUS := 39
- global HTML_I := 40
- global HTML_IMAGE := 41
- global HTML_IMG := 42
- global HTML_INPUT := 43
- global HTML_ISINDEX := 44
- global HTML_KBD := 45
- global HTML_L := 46
- global HTML_LI := 47
- global HTML_LINK := 48
- global HTML_LISTING := 49
- global HTML_LIT := 50
- global HTML_MARGIN := 51
- global HTML_MATH := 52
- global HTML_MENU := 53
- global HTML_NEXTID := 54
- global HTML_NOTE := 55
- global HTML_OL := 56
- global HTML_OPTION := 57
- global HTML_OVER := 58
- global HTML_P := 59
- global HTML_PERSON := 60
- global HTML_PLAINTEXT := 61
- global HTML_PRE := 62
- global HTML_Q := 63
- global HTML_QUOTE := 64
- global HTML_RENDER := 65
- global HTML_REMOVED := 66
- global HTML_S := 67
- global HTML_SAMP := 68
- global HTML_SELECT := 69
- global HTML_STRONG := 70
- global HTML_SUB := 71
- global HTML_SUP := 72
- global HTML_TAB := 73
- global HTML_TABLE := 74
- global HTML_TD := 75
- global HTML_TEXTAREA := 76
- global HTML_TH := 77
- global HTML_TITLE := 78
- global HTML_TR := 79
- global HTML_TT := 80
- global HTML_U := 81
- global HTML_UL := 82
- global HTML_VAR := 83
- global HTML_XMP := 84
- global HTML_XSCRIPTX := 85
- global HTML_LAST := 86
-
- global defaultStyle := #(@size:12, @underline:0, @weight:@regular, \
- @alignment:@fill, @paraindent:4, @indent:4, @indentfromend:4)
-
- method init self {object HTMLDisplayer} #rest args \
- #key url: callback: boundary: parent: browser: -> (
- apply nextmethod self args
- self.startX := 0
- self.startY := 0
- self.myParentGroup := parent
- self.myBoundary := boundary
-
- self.currentStyle := new KeyedLinkedList
- addMany self.currentStyle defaultStyle
- self.styleStack := new LinkedList
-
- startTextPresenter self
-
- self.url := url
- self.callback := callback
- self.state := @normal
- self.title := new String
- self.browser := browser
- self.stream := new HtmlStream \
- startElement: (displayer element #rest args -> apply startelement self element args) \
- endElement: (displayer element -> endElement self element) \
- putCharacter: (displayer ch -> putcharacter self ch)
- )
-
- method startElement self {object HTMLDisplayer} element #rest args -> (
- local fun := gethandler element
- if fun != undefined do apply fun self element true args
- )
-
- method endElement self {object HTMLDisplayer} element -> (
- local fun := gethandler element
- if fun != undefined do fun self element false
- )
-
- method startTextPresenter self {object HTMLDisplayer} -> (
- self.txt := new Text
- self.targetText := new Text
- self.pres := new TextPresenter target: self.targetText \
- boundary: (copy self.myBoundary)
- append self.myParentGroup self.pres
- self.pres.x := self.startX
- self.pres.y := self.startY
- foreachbinding self.currentStyle \
- (key value arg -> setattr self.txt key (size self.txt) value) \
- undefined
- )
-
- method finishTextPresenter self {object HTMLDisplayer} -> (
- if self.pres != undefined do (
- flushText self
- self.startY := self.startY + self.pres.height
- -- Nice to do this with width also
- if (size self.pres.target = 0) do (
- deleteOne self.myParentGroup self.pres
- )
- self.pres := undefined
- )
- )
-
- method putCharacter self {object HTMLDisplayer} character -> (
- if character == 13 do return
- case self.state of
- @title :
- append self.title character
- @verbatim:
- append self.txt character
- otherwise : (
- if character == 10 do character := 32
- append self.txt character
- )
- end
- local n := size self.txt
- if (n > 0 and (mod n 10000) = 0) do
- flushText self
- )
-
- function foo file -> (
- local s := getstream thestartdir file @readable
- local x := new htmldisplayer url: (new url string: ("http://www.kaleida.com/" + file))
- s | x
- plug s
- x
- )
-
- function crash -> (
- local y := new htmldisplayer
- local s := "<H2>The Kaleida Media Player</H2>"
- writestring y s
- writestring y s
- )
-
- -- Element handlers
- -- function self element startp present values ->
-
- global elementhandlers := new Array
- for i := 0 to HTML_LAST do append elementHandlers undefined
- function gethandler element -> elementHandlers[element + 1]
- function sethandler element fun -> elementHandlers[element + 1] := fun
-
-
- -- This does not have to be done. The TextPresenter seems to update itself anyway
-
- method noteChanged self {object HTMLDisplayer} -> (
- self.pres.changed := true
- )
-
- global headerStyles := #(HTML_H1:#(@weight:@bold, @size:18),
- HTML_H2:#(@weight:@bold, @size:14))
-
- function handleHTML_H self element start #rest args -> (
- if start then (
- newPara self
- pushStyle self
- local style := headerStyles[element]
- if style == empty then (
- setStyle self #(@weight:@bold)
- ) else (
- setStyle self style
- )
- ) else (
-
- popStyle self
- newPara self
- )
- )
-
- sethandler HTML_H1 handleHTML_H
- sethandler HTML_H2 handleHTML_H
- sethandler HTML_H3 handleHTML_H
- sethandler HTML_H4 handleHTML_H
- sethandler HTML_H5 handleHTML_H
- sethandler HTML_H6 handleHTML_H
- sethandler HTML_H7 handleHTML_H
-
- function handleHTML_P self element start #rest args -> (
- newPara self
- )
-
- sethandler HTML_P handleHTML_P
-
- -- This is a bit inefficient!!!
-
- method pushStyle self {object HTMLDisplayer} -> (
- prepend self.styleStack (new keyedlinkedlist)
- )
-
- method popStyle self {object HTMLDisplayer} -> (
- setStyle self self.styleStack[1]
- pop self.styleStack
- )
-
- method setStyleAttr self {object HTMLDisplayer} key idx value -> (
- local currentValue := self.currentStyle[key]
- for safe in self.styleStack do
- if (safe[key] = empty) do add safe key currentValue
- self.currentStyle[key] := value
- setattr self.txt key idx value
- )
-
- method setStyle self {object HTMLDisplayer} style -> (
- local idx := (size self.txt)
- foreachbinding style (key value arg -> setStyleAttr self key idx value) \
- undefined
- )
-
- global endOfLine := 13
-
- method newPara self {object HTMLDisplayer} -> (
- append self.txt endOfLine
- append self.txt endOfLine
- )
-
- function handleNewPara self element start #rest args -> (
- newPara self
- )
-
- sethandler HTML_LI handleNewPara
- sethandler HTML_DL handleNewPara
- sethandler HTML_DT handleNewPara
- sethandler HTML_DD handleNewPara
-
- function handle_HR self element start #rest args -> (
- finishTextPresenter self
- local p := new TwoDShape \
- fill: blackbrush \
- stroke: blackbrush \
- boundary: (new line x2: self.myBoundary.width y2: 0)
-
- p.x := self.startX
- p.y := self.startY
- self.startY := self.startY + 3
- append self.myParentGroup p
- startTextPresenter self
- )
-
- sethandler HTML_HR handle_HR
-
- function setStyleHandler element style -> (
- sethandler element \
- (self element start #rest args -> (
- if start then (
- pushStyle self
- setStyle self style
- ) else (
- popStyle self
- )
- ))
- )
-
- setStyleHandler HTML_B #(@weight:@bold)
-
- function handleHTML_A self element start #rest args #key href: -> (
- if start then (
- if (href != unsupplied) do (
- self.anchorStart := size self.txt
-
- if (self.url != undefined) do (
- if (not (isaKindof href url)) do
- href := new url string: href
- self.anchorURL := merge href self.url
- )
-
- pushStyle self
- setStyle self #(@underline:2)
- )
- ) else (
- if (self.anchorStart != undefined) do (
- local anchorend := size self.txt
- local destinationurl := self.anchorurl
- popstyle self
- setattrfromto self.txt @action self.anchorstart anchorend \
- (#rest args -> gotourl self destinationurl )
- self.anchorstart := undefined
- self.anchorURL := undefined
- )
- )
- )
-
- sethandler HTML_A handleHTML_A
-
- function handleHTML_TITLE self element start #rest args #key href: -> (
- self.state := if start then @title else @normal
- )
-
- function handleHTML_PRE self element start #rest args -> (
- if start then (
- pushStyle self
- self.state := @verbatim
- ) else (
- popStyle self
- self.state := @normal
- setStyle self #(@alignment:@tty)
- )
- )
-
- sethandler HTML_TITLE handleHTML_TITLE
- sethandler HTML_PRE handleHTML_PRE
-
- ---
-
- method gotoURL self {object htmldisplayer} url -> (
- self.callback self url
- )
-
- method clear self {object htmldisplayer} -> (
- emptyOut self.txt
- emptyOut self.targetText
- )
-
-
- method plug self {object htmldisplayer} -> (
- plug self.stream
- finishTextPresenter self
- )
-
- method flushText self {object htmldisplayer} -> (
- ht := self
- insertAt self.targettext self.txt (size self.targetText)
- emptyOut self.txt
- if (size self.pres.target > 0) do (
- local top := self.pres.presentedby
- repeat until top.presentedby = undefined do top := top.presentedby
- setContext self.pres top.displaysurface top.bbox
- self.pres.height := calculate self.pres @width self.pres.width
- noteChanged self
- )
- )
-
- --
-
- function handleHTML_XSCRIPTX self element start #rest args #key width: height: src: -> (
- finishTextPresenter self
- width := width as integer
- height := height as integer
- local p := new TwoDMultiPresenter boundary: (new Rect x2: width y2: height)
- p.x := self.startX
- p.y := self.startY
- append self.myParentGroup p
-
- -- Error
- local tc := openContainerFromURL (merge (new url string: src) self.url)
-
- new tc[1] parent: p browser: self.browser tc: tc
-
- self.startY := self.startY + height
- startTextPresenter self
- )
-
- sethandler HTML_XSCRIPTX handleHTML_XSCRIPTX
-
- print "image support is commented out"
-
- function handleHTML_IMG self element start #rest args #key width: height: src: -> (
- -- This html parser does not support width/height!
- -- We should not download the whole thing if we do not know the image type
- /*
- local stuff := getURLToTempFile (merge (new url string: src) self.url)
- local file := stuff[2]
- local type := getone stuff[1] ("content-type" as string)
- if (type = ("image/gif" as string)) then (
- finishTextPresenter self
- print src
- local myStream := getStream theTempDir file @Readable
- local myBitmap := importMedia theImportExportEngine myStream @image @GIF @bitmap
- print #("done", src)
- local bp := new TwoDShape target:myBitmap fill:blackBrush -- stroke:blackBrush
- bp.x := self.startX
- bp.y := self.startY
- append self.myParentGroup bp
- self.startY := self.startY + bp.height
- plug myStream
- startTextPresenter self
- ) else (
- print #("unknown image type", type)
- )
-
- */
- )
-
- sethandler HTML_IMG handleHTML_IMG
-
- -->>>
-